package cn.sharp.bbs.service.impl;

import cn.sharp.bbs.common.Constants;
import cn.sharp.bbs.dao.FlowDao;
import cn.sharp.bbs.dao.gen.LabelMapper;
import cn.sharp.bbs.entity.BO.CurrentUser;
import cn.sharp.bbs.entity.DO.*;
import cn.sharp.bbs.service.FlowService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.*;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author zhao yu
 * TODO:最新、最热、关注、推荐
 */
@Service
@Transactional
public class FlowServiceImpl implements FlowService {

    @Resource
    private FlowDao flowDao;

    @Resource
    private LabelMapper labelMapper;

    @Override
    public List<PostDto> getFlow(int area, int type, int label, CurrentUser user) {
        // post info & author info
        List<PostDto> list = flowDao.getFlow(area, type, label);
        getInfo(list, user);
        return list;
    }

    private void getInfo(List<PostDto> list, CurrentUser user) {
        for (int i = 0, len = list.size(); i < len; i++) {
            PostDto post = list.get(i);
            // post author avatar
            post.setAuthorAvatar(Constants.AVATAR_URL + post.getAuthorAvatar());
            // post version info
            PostDto version = flowDao.getVersion(post.getPostId());
            if (version == null) {
                list.remove(i);
                len--;
                i--;
                continue;
            }
            post.setTitle(version.getTitle());
            post.setContent((version.getContent()));
            post.setTime(version.getTime());
            PostDto img = flowDao.getPostImg(post.getPostId());
            post.setImg(img == null ? null : img.getImg());
            // label info
            post.setLabels(flowDao.getLabel(post.getPostId()));
            // current user's interaction info
            if (user != null) {
                post.setLike(flowDao.ifLike(user.getU_id(), post.getPostId()) > 0);
                post.setCollect(flowDao.ifCollect(user.getU_id(), post.getPostId()) > 0);
                post.setFollowPost(flowDao.ifFollowPost(user.getU_id(), post.getPostId()) > 0);
                post.setFollowAuthor(flowDao.ifFollowAuthor(user.getU_id(), post.getAuthorId()) > 0);
            }
            //interaction info
            post.setLikeCount(flowDao.likeCount(post.getPostId()));
            post.setCollectCount(flowDao.collectCount(post.getPostId()));
            post.setFollowPostCount(flowDao.followPostCount(post.getPostId()));

        }
    }

    @Override
    public List<PostDto> getLatestFlow(CurrentUser user) {
        List<PostDto> list = flowDao.getLatest();
        getInfo(list, user);
        return list;
    }

    @Override
    public List<PostDto> getHottestFlow(CurrentUser user) {
        List<PostDto> list = flowDao.getHottest();
        getInfo(list, user);
        return list;
    }

    @Override
    public List<PostDto> getFlowByFollow(CurrentUser user) {
        List<PostDto> list = flowDao.getFollow(user.getU_id());
        getInfo(list, user);
        return list;
    }

    @Override
    public List<PostDto> getPersonalizedFlow(CurrentUser user) {
        List<PostDto> list = flowDao.getPersonalized(user.getU_id());
        getInfo(list, user);
        return list;
    }

    @Override
    public List<Label> getLabelList() {
        return labelMapper.selectAll();
    }

    /**
     * 每小时更新热榜
     */
    @Scheduled(cron = "0 0 0/1 * * ?")
    protected void updateHottestFlow() {
        List<Score> list = flowDao.getPostPassTime();
        for (Score score : list) {
            Long p = flowDao.likeCount(score.getPostId());
            score.setScore((p - 1) / Math.pow(score.getHour() + 1 + 2, 1.8));
            flowDao.updateHour(score.getPostId(), score.getHour() + 1, score.getScore());
        }
    }

    /**
     * 每隔十二小时更新个性化推荐
     */
    @Scheduled(cron = "0 0 0/12 * * ?")
    protected void updatePersonalizedFlow() {
        System.out.println("\nupdate personalized post");
        List<BrowseRecord> list = flowDao.getBrowseRecordList();
        try (PrintWriter writer = new PrintWriter(new File("src\\main\\python\\data\\browseRecord.csv"))) {
            for (BrowseRecord record : list) {
                writer.write(record.toString());
            }
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        }

        try {
            Process proc = Runtime.getRuntime().exec("python src\\main\\python\\bin\\update.py");
            proc.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try (Scanner scanner = new Scanner(new File("src\\main\\python\\data\\recommend.csv"))) {
            flowDao.deleteAll();
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                System.out.println(line);
                String[] recommend = line.split(",");
                flowDao.insertPersonalized(Long.valueOf(recommend[0]), Long.valueOf(recommend[1]));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //富文本转纯文本 杨择润补充
    public static String getText(String richText) {
        String regx = "(<.+?>)|(</.+?>)";
        Matcher matcher = Pattern.compile(regx).matcher(richText);
        while (matcher.find()) {
            // 替换图片
            richText = matcher.replaceAll("").replace(" ", "");
        }
        return richText;
    }

}
